﻿#region Copyright Notice

//Copyright © 2007-2011, PARROT SA, all rights reserved. 

//DISCLAIMER 
//The APIs is provided by PARROT and contributors "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability 
//and fitness for a particular purpose are disclaimed. In no event shall PARROT and contributors be liable for any direct, indirect, incidental, special, exemplary, or 
//consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however 
//caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this 
//software, even if advised of the possibility of such damage. 

//Author            : Wilke Jansoone
//Email             : wilke.jansoone@digitude.net
//Publishing date   : 28/11/2010 

//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
//are met:
//    - Redistributions of source code must retain the above copyright notice, this list of conditions, the disclaimer and the original author of the source code.
//    - Neither the name of the PixVillage Team, nor the names of its contributors may be used to endorse or promote products derived from this software without 
//      specific prior written permission.

#endregion

#region Imports

using System;
using System.Collections.Generic;

#endregion

namespace Wilke.Interactive.Drone.Control
{
    internal sealed class UnsafeHelpers
    {
        internal unsafe static void ByteArrayCopy(byte[] sourceArray, long sourceIndex, byte[] destinationArray, long destinationIndex, long count)
        {
            if (sourceArray == null || sourceIndex < 0 ||
                destinationArray == null || destinationIndex < 0 || count < 0)
            {
                throw new System.ArgumentException();
            }

            int sourceArrayLength = sourceArray.Length;
            int destinationArrayLength = destinationArray.Length;
            if (sourceArrayLength - sourceIndex < count || destinationArrayLength - destinationIndex < count)
            {
                throw new System.ArgumentException();
            }

            // The following fixed statement pins the location of the src and dst objects
            // in memory so that they will not be moved by garbage collection.
            fixed (byte* pSrc = sourceArray, pDst = destinationArray)
            {
                byte* ps = pSrc + sourceIndex;
                byte* pd = pDst + destinationIndex;

                // Loop over the count in blocks of 4 bytes, copying an integer (4 bytes) at a time:
                for (int i = 0; i < count / 4; i++)
                {
                    *((int*)pd) = *((int*)ps);
                    pd += 4;
                    ps += 4;
                }

                // Complete the copy by moving any bytes that weren't moved in blocks of 4:
                for (int i = 0; i < count % 4; i++)
                {
                    *pd = *ps;
                    pd++;
                    ps++;
                }
            }
        }
    }
}
